#include <sys_head.h>
#include "sql_list.h"
/*
当新用户 加入群聊
    向所有用户发送 xxx 加入了群聊

新用户修改昵称 修改昵称
    新用户发送 set_name_名字

用户发送信息
    给出发送用户外的其他用户转发


如何实现
    线性表  链表 或者 顺序表

    顺序表

顺序表的结构

*/
void Server(int Sock_fd);

int main(int argc, char const *argv[])
{
    // 判断命令行参数
    if (argc < 2)
    {
        printf("参数错误:%s ip port\n", argv[0]);
        return -1;
    }
    // 给定默认ip

    char ip_str[128];

    if (3 != argc)
    {

        strcpy(ip_str, "10.0.12.15");
    }
    else
    {

        strcpy(ip_str, argv[2]);
    }

    // 1、创建用户数据报 套接字
    int Udp_Sock_fd = socket(AF_INET, SOCK_DGRAM, 0);

    // 2、填充服务器网络信息结构体
    struct sockaddr_in Udp_Sock_addr;
    Udp_Sock_addr.sin_family = AF_INET;
    Udp_Sock_addr.sin_port = htons(atoi(argv[1]));
    Udp_Sock_addr.sin_addr.s_addr = inet_addr(ip_str);

    socklen_t Udp_Sock_size = sizeof(Udp_Sock_addr);

    // 3、将套接字与服务器的网络信息结构体绑定
    bind(Udp_Sock_fd, (struct sockaddr *)&Udp_Sock_addr, Udp_Sock_size);

    // 4、收发数据

    Server(Udp_Sock_fd);

    close(Udp_Sock_fd);

    // 5、关闭套接字
    return 0;
}

void Server(int Sock_fd)
{
    // 编写群聊

    // 定义变量
    struct sockaddr_in Udp_Sock_client;
    socklen_t Udp_Sock_client_size = sizeof(Udp_Sock_client);

    char buf[1024] = " "; // 创建接收缓冲区
    char send_buf[2048] = " ";

    int find_index = 0;

    // 初始化顺序表
    UDP_client_sql *list = NULL;
    sql_list_init(&list);

    // 定义数据
    UDP_client_data Client_data;

    while (1)
    {
        // 清空数据
        memset(buf , 0 , sizeof(buf));
        memset(send_buf , 0 , sizeof(send_buf));
        memset(&Udp_Sock_client , 0 , sizeof(Udp_Sock_client));

        // 接收
        recvfrom(Sock_fd, buf, sizeof(buf), 0, (struct sockaddr *)&Udp_Sock_client, &Udp_Sock_client_size);
        
        Client_data.data = Udp_Sock_client;

        // ======================================  添加用户  ======================================
        if (NULL != strstr(buf, "new_"))
        {
            strcpy(Client_data.name, buf + 4);

            // 查找是否已经有这个用户
            if (-1 != sql_list_find(list, Client_data))
            {
                // 已经有这个用户的 直接退出
                continue;;
            }
            else
            {
                sql_list_insert(list, Client_data, list->len + 1);
                // 回发修改成功
                
                memset(buf , 0 , sizeof(buf));
                sprintf( buf , "%s 加入群聊" , Client_data.name);

                for (size_t i = 0; i < list->len; i++)
                {
                    sendto(Sock_fd , buf , strlen(buf) , 0 , (struct sockaddr *)&list->data[i].data , sizeof(list->data[i].data) );
                }
            }
        }

        // ======================================  设定昵称  ======================================
        else if (NULL != strstr(buf, "set_name_"))
        {

            // 查找用户

            if (-1 == (find_index = sql_list_find(list, Client_data)))
            {
                break;
            }

            // 修改昵称
            sql_list_set_name(list, find_index, buf + 9);
        }

        // ======================================  转发信息  ======================================

        else
        {
            // 组装字符串
            find_index = sql_list_find(list, Client_data);

            sprintf(send_buf, "%s : %s", list->data[find_index].name, buf);

            for (size_t i = 0; i < list->len; i++)
            {
                if (sql_list_cmp(list->data[i] , Client_data))
                {
                    sendto(Sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&list->data[i].data, sizeof(list->data[i].data));
                }
            }
        }
    }
}

/*
链接请求
    new_昵称

zhangsna zhang



*/


